package com.insigma.business.qrcode.soldier.service.impl;

import com.google.common.collect.Lists;

import com.insigma.business.qrcode.common.util.SpringContextUtil;
import com.insigma.business.qrcode.soldier.dto.SoldierBasicInfoBSearcher;
import com.insigma.business.qrcode.soldier.entity.SoldierBasicInfoDO;
import com.insigma.business.qrcode.soldier.service.BaseQueryService;
import com.insigma.business.qrcode.soldier.service.SoldierBasicInfoService;
import com.insigma.business.qrcode.soldier.util.RedisLock;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicInteger;


@Slf4j
@Component
public class StableThirdPartyRefresher {
    @Autowired
    private RedisLock redisLock;

    @Autowired
    private SoldierBasicInfoService soldierBasicInfoService;

    private List<BaseQueryService> thirdPartyServices;

    private String nowIdCardNo = "330103193601151635";

    private int threadCount = 30;

    public void initService() {
        List<BaseQueryService> list = Lists.newArrayList();
        list.add((BaseQueryService) SpringContextUtil.getBean("destituteInfoRefresher"));
        list.add((BaseQueryService)SpringContextUtil.getBean("carInfoRefresher"));
        list.add((BaseQueryService)SpringContextUtil.getBean("effectiveJudgmentInfoRefresher"));
        list.add((BaseQueryService)SpringContextUtil.getBean("floatingPopulationRefresher"));
        list.add((BaseQueryService)SpringContextUtil.getBean("governmentPensionInsuranceRefresher"));
        list.add((BaseQueryService)SpringContextUtil.getBean("providentFundInfoRefresher"));
        list.add((BaseQueryService)SpringContextUtil.getBean("shareholderInfoRefresher"));
        list.add((BaseQueryService)SpringContextUtil.getBean("socialSecurityInfoRefresher"));
        list.add((BaseQueryService)SpringContextUtil.getBean("subsistenceInfoInfoRefresher"));
        thirdPartyServices = list;
    }

    public void refresh() {
        boolean lock = redisLock.tryLock("test-basic-info");
        log.info("tryLock:result:{}",lock);
        if (!lock) {
            return ;
        }
        initService();
        log.info("serivceCount:{}", thirdPartyServices.size());
        log.info("start to reflash");
        List<SoldierBasicInfoDO> search = soldierBasicInfoService.search(new SoldierBasicInfoBSearcher(1, Integer.MAX_VALUE));
        
        List<SoldierBasicInfoDO> rList = Lists.newArrayList();
        Iterator<SoldierBasicInfoDO> iterator = search.iterator();
        while(iterator.hasNext()) {
            SoldierBasicInfoDO next = iterator.next();
            if (next.getRootAdminAreaCode() != null && next.getRootAdminAreaCode().startsWith("330110")) {
                rList.add(next);
                iterator.remove();
            }
        }
        rList.addAll(search);
        AtomicInteger aCount = new AtomicInteger(0);

        if (Strings.isNotBlank(nowIdCardNo)) {
            Iterator<SoldierBasicInfoDO> rlistI = rList.iterator();
            while (rlistI.hasNext()) {
                aCount.incrementAndGet();
                SoldierBasicInfoDO next = rlistI.next();
                if (next.getIdCardNo().equals(nowIdCardNo)) {
                    rlistI.remove();
                    break;
                }
                rlistI.remove();
            }
        }

        ConcurrentLinkedQueue<SoldierBasicInfoDO> queue = new ConcurrentLinkedQueue<SoldierBasicInfoDO>();
        for (SoldierBasicInfoDO soldierBasicInfoDO : rList) {
            queue.add(soldierBasicInfoDO);
        }

        for (int i = 0; i < threadCount; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    while(!queue.isEmpty()) {
                        SoldierBasicInfoDO soldierBasicInfoDO = queue.poll();
                        log.info("loop:{},   idccard: {}", aCount.incrementAndGet(), soldierBasicInfoDO.getIdCardNo());

                        String idCardNO = soldierBasicInfoDO.getIdCardNo();
                        String name = soldierBasicInfoDO.getRealName();

                        for (BaseQueryService thirdPartyService : thirdPartyServices) {
                            thirdPartyService.execute(idCardNO, name);
                        }
                    }
                }
            }).start();
        }
    }
}
